package com.suray.wcs.web.system.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.suray.basic.wcs.path.core.Node;
import com.suray.basic.wcs.path.enums.NodeStatus;
import com.suray.basic.wcs.path.enums.NodeType;
import com.suray.basic.wcs.plc.core.Plc;
import com.suray.basic.wcs.plc.entity.PlcDeviceDB;
import com.suray.basic.wcs.plc.enums.Network;
import com.suray.basic.wcs.plc.enums.PlcDeviceType;
import com.suray.basic.wcs.plc.pojo.oper.DismountingDiskMachineOper;
import com.suray.basic.wcs.plc.pojo.oper.lifter.LifterOper;
import com.suray.basic.wcs.plc.pojo.oper.StationOper;
import com.suray.basic.wcs.plc.service.impl.PlcDeviceDBServiceImpl;
import com.suray.basic.wcs.utils.Coord;
import com.suray.commin.annotation.InterfaceLog;
import com.suray.wcs.service.init.SystemInit;
import com.suray.wcs.service.pojo.Rgv;
import com.suray.wcs.service.system.entity.NodeDB;
import com.suray.wcs.service.system.service.impl.NodeDBServiceImpl;
import com.suray.wcs.service.wmsconnect.dto.*;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.util.CollectionUtils;
import org.assertj.core.util.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @author caox@suray.cn
 * @description:三维监控接口
 * @date 2020/9/7 14:29
 */
@RestController
@RequestMapping("/thrDimMonitor")
public class ThreeDimensionalMonitorController {

    @Autowired
    private NodeDBServiceImpl nodedbService;

    @Autowired
    private PlcDeviceDBServiceImpl plcdevicedbServiceImpl;

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @PostMapping("/getRgvInfo")
    @ResponseBody
    @ApiOperation(value = "返回小车信息")
    @InterfaceLog(value = "返回小车信息", sender = "MONITOR", recipient = "WCS")
    public List<RgvInfoDto> getRgvInfo() {
        List<RgvInfoDto> devices = new ArrayList<RgvInfoDto>();
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(SystemInit.RGVS)) {
            for (Rgv rgv : SystemInit.RGVS) {
                RgvInfoDto re = new RgvInfoDto();
                re.setRgvNo(rgv.getRgvDB().getRgvNo());
                re.setStatus(rgv.getRgvResStatus().getRgvStatus());
                re.setIsPalletExist(rgv.isHasCargo() ? NodeStatus.Y.toString() : NodeStatus.N.toString());
                re.setLocation(rgv.getCurLocationStr());
                re.setInfo(rgv.getErrorMessage());
                devices.add(re);
            }
        }
        return devices;
    }

    /**
     * @param nodeListDto
     * @return String
     * @Description:WMS货位状态查询接口
     * @author rbj
     */
    @PostMapping("/getNodeList")
    @ResponseBody
    @ApiOperation(value = "获取货位信息")
    @InterfaceLog(value = "获取货位信息", sender = "MONITOR", recipient = "WCS")
    public List<NodeDto> getNodeList(@RequestBody NodeListDto nodeListDto) {
        log.info("接收到上位系统<货位状态查询>请求，参数-->" + nodeListDto);
        String district = nodeListDto.getDistrict();
        List<NodeDto> nodeDtoList = Lists.newArrayList();
        if (StringUtils.isBlank(district)) {
            return nodeDtoList;
        }
        List<NodeDB> nodeDBList = nodedbService.list(
                new QueryWrapper<NodeDB>().lambda().eq(NodeDB::getGridStatus, NodeStatus.Y.toString()).eq(NodeDB::getGridType, NodeType.P.getCode()));
        if (!CollectionUtils.isEmpty(nodeDBList)) {
            for (NodeDB nodedb : nodeDBList) {
                nodeDtoList.add(buildNodeDto(nodedb));
            }
        }
        return nodeDtoList;
    }

    private NodeDto buildNodeDto(NodeDB nodeDBRes) {
        NodeDto nodeDto = new NodeDto();
        nodeDto.setCargoLocationId(nodeDBRes.getGridId());
        nodeDto.setCargoLocationStatus(nodeDBRes.getGridStatus());
        nodeDto.setCoord(new Coord(nodeDBRes.getGridx(), nodeDBRes.getGridy(), nodeDBRes.getGridz()).toString());
        return nodeDto;
    }

    /**
     * @param nodeListDto
     * @return String
     * @Description:WMS货位状态查询接口
     * @author rbj
     */
    @PostMapping("/getAllNode")
    @ResponseBody
    @ApiOperation(value = "获取货位信息")
    @InterfaceLog(value = "获取货位信息", sender = "MONITOR", recipient = "WCS")
    public List<AllNodeDto> getAllNode(@RequestBody NodeListDto nodeListDto) {
        log.info("接收到上位系统<货位状态查询>请求，参数-->" + nodeListDto);
        String district = nodeListDto.getDistrict();
        List<AllNodeDto> nodeDtoList = Lists.newArrayList();
        if (StringUtils.isBlank(district)) {
            return nodeDtoList;
        }
        List<NodeDB> nodeDBList = nodedbService.list();
        if (!CollectionUtils.isEmpty(nodeDBList)) {
            for (NodeDB nodedb : nodeDBList) {
                nodeDtoList.add(buildAllNodeDto(nodedb));
            }
        }
        return nodeDtoList;
    }

    private AllNodeDto buildAllNodeDto(NodeDB nodedb) {
        AllNodeDto allNodeDto = new AllNodeDto();
        allNodeDto.setType(nodedb.getGridType().getCode());
        allNodeDto.setStatus(nodedb.getGridStatus());
        allNodeDto.setCoord(new Coord(nodedb.getGridx(), nodedb.getGridy(), nodedb.getGridz()).toString());
        allNodeDto.setCanToDown(nodedb.getCanToDown());
        allNodeDto.setCanToUp(nodedb.getCanToUp());
        allNodeDto.setCanToLeft(nodedb.getCanToLeft());
        allNodeDto.setCanToRight(nodedb.getCanToRight());
        return allNodeDto;
    }

    /**
     * @Description:MONITOR获取工位信息查询接口
     * @author rbj
     */
    @PostMapping("/getChainStationList")
    @ResponseBody
    @ApiOperation(value = "获取工位信息")
    @InterfaceLog(value = "获取工位信息", sender = "MONITOR", recipient = "WCS")
    public List<StationDto> getChainStationList() {
        List<StationDto> stationDtoList = Lists.newArrayList();

        List<PlcDeviceDB> plcDeviceDBList = plcdevicedbServiceImpl.queryPlcDevices(
                new ArrayList<>(Arrays.asList(PlcDeviceType.CHAIN_STATION.getTypeNum(),
                        PlcDeviceType.MONOMER_CONVEYOR.getTypeNum())));
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(plcDeviceDBList)) {
            for (PlcDeviceDB plcdevicedb : plcDeviceDBList) {
                StationDto stationDto = new StationDto();
                Node node = Node.parseGrid(plcdevicedb.getDeviceLocation());
                StationOper stationOper = (StationOper) Plc.deviceStationCoordMap.get(new Coord(node.getX(), node.getY(), node.getZ()));
                if (stationOper == null) {
                    stationDto.setNo(plcdevicedb.getDeviceNo());
                    stationDto.setStatus(Network.OFF_LINE.getNetWorkNum());
                    stationDto.setIsPalletExist(NodeStatus.N.toString());
                    stationDto.setCoord(plcdevicedb.getDeviceLocation().replace(",)", ")"));
                } else {
                    stationDto.setNo(stationOper.getDeviceNo());
                    stationDto.setStatus(Network.ON_LINE.getNetWorkNum());
                    stationDto.setIsPalletExist(stationOper.isPalletExist() ? NodeStatus.Y.toString() : NodeStatus.N.toString());
                    stationDto.setCoord(stationOper.getCoord().toString());
                }
                stationDtoList.add(stationDto);
            }
        }
        return stationDtoList;
    }

    /**
     * @Description:MONITOR获取拆叠盘机工位信息查询接口
     * @author rbj
     */
    @PostMapping("/getDsihStationList")
    @ResponseBody
    @ApiOperation(value = "获取拆叠盘机工位信息")
    @InterfaceLog(value = "获取拆叠盘机工位信息", sender = "MONITOR", recipient = "WCS")
    public List<StationDto> getDsihStationList() {
        List<StationDto> stationDtoList = Lists.newArrayList();
        List<PlcDeviceDB> plcDeviceDBList = plcdevicedbServiceImpl.queryPlcDevices(
                new ArrayList<>(Collections.singletonList(PlcDeviceType.DSIHSTATION.getTypeNum())));
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(plcDeviceDBList)) {
            for (PlcDeviceDB plcdevicedb : plcDeviceDBList) {
                StationDto stationDto = new StationDto();
                DismountingDiskMachineOper dismountingDiskMachineOper = (DismountingDiskMachineOper) Plc.deviceBaseNameMap.get(plcdevicedb.getDeviceName());
                if (dismountingDiskMachineOper == null) {
                    stationDto.setNo(plcdevicedb.getDeviceNo());
                    stationDto.setStatus(Network.OFF_LINE.getNetWorkNum());
                    stationDto.setIsPalletExist(NodeStatus.N.toString());
                    stationDto.setCoord(plcdevicedb.getDeviceLocation().replace(",)", ")"));
                } else {
                    stationDto.setNo(dismountingDiskMachineOper.getDeviceNo());
                    stationDto.setStatus(Network.ON_LINE.getNetWorkNum());
                    stationDto.setIsPalletExist(dismountingDiskMachineOper.isPalletExist() ? NodeStatus.Y.toString() : NodeStatus.N.toString());
                    stationDto.setCoord(dismountingDiskMachineOper.getCoord().toString());
                }
                stationDtoList.add(stationDto);
            }
        }
        return stationDtoList;
    }

    /**
     * @Description:MONITOR获取提升机信息查询接口
     * @author rbj
     */
    @PostMapping("/getLifterList")
    @ResponseBody
    @ApiOperation(value = "获取提升机信息")
    @InterfaceLog(value = "获取提升机信息", sender = "MONITOR", recipient = "WCS")
    public List<LifterDto> getLifterList() {
        List<LifterDto> lifterDtoList = Lists.newArrayList();
        List<PlcDeviceDB> liftList = plcdevicedbServiceImpl.queryLiftList();
        if (org.apache.commons.collections.CollectionUtils.isNotEmpty(liftList)) {
            for (PlcDeviceDB plcdevicedb : liftList) {
                LifterDto lifterDto = new LifterDto();
                LifterOper lifterOper = (LifterOper) Plc.deviceBaseNameMap.get(plcdevicedb.getDeviceName());
                if (lifterOper == null) {
                    lifterDto.setNo(plcdevicedb.getDeviceNo());
                    lifterDto.setStatus(Network.OFF_LINE.getNetWorkNum());
                    lifterDto.setIsPalletExist(NodeStatus.N.toString());
                    lifterDto.setCoord(plcdevicedb.getDeviceLocation().replace(",)", ")"));
                    lifterDto.setCurLayer(null);
                } else {
                    lifterDto.setNo(plcdevicedb.getDeviceNo());
                    lifterDto.setStatus(Network.ON_LINE.getNetWorkNum());
                    lifterDto.setIsPalletExist(lifterOper.isHaveCargo() ? NodeStatus.Y.toString() : NodeStatus.N.toString());
                    lifterDto.setCoord(plcdevicedb.getDeviceLocation().replace(",)", ")"));
                    lifterDto.setCurLayer(lifterOper.getHoistCurrentLayer());
                }
                lifterDtoList.add(lifterDto);
            }
        }
        return lifterDtoList;
    }

}
